<?php

namespace Base;

use W3\Widget;
use W3\Util;
use W3\Timer;
use W3\Router;
use W3\Db\Query;
use function action_exists;
use function do_action;

/**
 * 评论基类
 *
 * @author edikud
 * @date 2022/10/22
 * @copyright Copyright (c) 2022 W3 (http://www.mcooo.com)
 * @license GNU General Public License 2.0
 */
class Comments extends Widget
{
    /**
     * 获取查询对象
     *
     * @return Query
     * @throws Exception
     */
    public function select(...$args): Query
    {
		return do_action( 
		    $this->parameter->main . '.select',
			$this,
			false,
			$this->db->select(...$args)->from('table.comments')
		);
    }
	
    /**
     * 获取当前内容结构
     *
     * @access protected
     * @return array
     */
    protected function ___parentRow(): ?array
    {
		return $this->widget('Contents\Rows@' . $this->cid, 
		    ['cid'=>$this->cid])->row;
    }

    /**
     * 获取当前评论标题
     *
     * @access protected
     * @return string
     */
    protected function ___title(): ?string
    {
        return $this->parentRow['title'];
    }

    /**
     * 获取当前评论链接
     *
     * @access protected
     * @return string
     */
    protected function ___permalink(): string
    {
        if ($this->config->commentsPageBreak && 'approved' == $this->status) {
            $coid = $this->coid;
			$parent = $this->parent;

            while ($parent > 0 && $this->config->commentsThreaded) 
			{
                $parentRows = $this->db
				    ->select('parent')
					->from('table.comments')
                    ->where('coid = ? AND status = ?', $parent, 'approved')
					->limit(1)
					->fetch();

                if (!empty($parentRows)) {
                    $coid = $parent;
                    $parent = $parentRows['parent'];
                } else {
                    break;
                }
            }

            $comments = $this->db
			    ->select('coid', 'parent')
			    ->from('table.comments')
                ->where('cid = ? AND status = ?', $this->parentRow['cid'], 'approved')
                ->where('coid ' . ('DESC' == $this->config->commentsOrder ? '>=' : '<=') . ' ?', $coid)
                ->order('coid', 'ASC')
			    ->get();

            $commentsMap = [];
            $total = 0;
            
            foreach ($comments as $comment) 
			{
                $commentsMap[$comment['coid']] = $comment['parent'];
                
                if (0 == $comment['parent'] || !isset($commentsMap[$comment['parent']])) {
                    $total ++;
                }
            }

            $currentPage = ceil($total / $this->config->commentsPageSize);
		
            $pageRow = $this->parentRow + ['commentPage' => $currentPage];
			
            return Router::buildUrl('comment_page', $pageRow) . '#' . $this->theId;
        }
        
        return $this->parentRow['permalink'] . '#' . $this->theId;
    }

    /**
     * 获取当前评论内容
     *
     * @access protected
     * @return string
     */
    protected function ___content(): ?string
    {
		/** 插件接口 */
		return do_action('comments_text', $this, false, $this->text);
    }

    /**
     * 输出词义化日期
     *
     * @access protected
     * @return string
     */
    protected function ___dateWord(): string
    {
        return $this->date->word();
    }

    /**
     * 锚点id
     *
     * @access protected
     * @return string
     */
    protected function ___theId(): string
    {
        return 'comment-' . $this->coid;
    }

    /**
     * 通用过滤器
     *
     * @access public
     * @param array $value 需要过滤的行数据
     * @return array
     */
    public function filter(array $value): array
    {
        $value['date'] = Timer::make($value['created'] ?? NULL);
		
		/** 插件接口 */
		$value = do_action('comments_filter', $this, false, $value);
		
        return $value;
    }

    /**
     * 将每行的值压入堆栈
     *
     * @access public
     * @param array $value 每行的值
     * @return array
     */
    public function push(array $value): array
    {
        $value = $this->filter($value);
        return parent::push($value);
    }

    /**
     * 评论是否可以被修改
     *
     * @access public
     * @return boolean
     */
    public function allow(string $permission): bool
    {
        if ('edit' == $permission) {
            $allow = $this->have() && ($this->auth->check('editor', true) || $this->ownerId == $this->auth->uid);
        } else {
			$permission = 'allow' . ucfirst($permission);
            $allow = $this->{$permission} == 1;
        }		
        return $allow;
    }
	
    /**
     * 输出文章发布日期
     *
     * @access public
     * @param string $format 日期格式
     * @return void
     */
    public function date(?string $format = NULL)
    {
        echo Timer::make()->format(empty($format) ? $this->config->commentDateFormat : $format);
    }

    /**
     * 调用用户
     *
     * @access public
     * @return void
     */
    protected function ___author(): Widget
    {
        return $this->widget(
		    'User\Rows@' . $this->uid, 
		    ['uid' => $this->uid, 'limit' => 1]
		);
    }

    /**
     * 输出评论摘要
     *
     * @access public
     * @param integer $length 摘要截取长度
     * @param string $trim 摘要后缀
     * @return void
     */
    public function excerpt($length = 100, $trim = '...')
    {
        echo Util::substr(strip_tags($this->text), 0, $length, $trim);
    }
}

